﻿namespace AnyOffice.WebControls
{
    using MySql.Data.MySqlClient;
    using System;
    using System.ComponentModel;
    using System.Data;
    using System.Runtime.CompilerServices;
    using System.Web.Caching;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;

    [DefaultProperty("SelectCommand"), ToolboxData("<{0}:MySqlPager runat=\"server\" />"), DefaultEvent("PageIndexChanged")]
    public class MySqlPager : WebControl, INamingContainer
    {
        private static object _control;
        private Control _controlToPaginate = null;
        private PagedDataSource _dataSource = null;
        private static int _RecordCount = 0;
        private string CurrentPageText = "共&nbsp{2}&nbsp条记录&nbsp--&nbsp第&nbsp{0}&nbsp页&nbsp--&nbsp共&nbsp{1}&nbsp页";
        private string NoPageSelectedText = "";
        private string QueryCountCommandText = "SELECT COUNT(*) FROM ({0}) AS t0";
        private string QueryPageCommandText = "SELECT * FROM (SELECT  * FROM (SELECT  * FROM ({2}) AS t0 ORDER BY {3} {4}) AS t1 ORDER BY {3} {5} limit {1}) AS t2 ORDER BY {3} {4} limit {0}";

        public event PageChangedEventHandler PageIndexChanged;

        public MySqlPager()
        {
            this.PagingMode = AnyOffice.WebControls.PagingMode.Cached;
            this.PagerStyle = AnyOffice.WebControls.PagerStyle.NextPrev;
            this.CurrentPageIndex = 0;
            this.SelectCommand = "";
            this.ConnectionString = "";
            this.ItemsPerPage = 10;
            this.TotalPages = -1;
            this.TotalRecord = -1;
            this.CacheDuration = 60;
        }

        private void AdjustSelectCommand(bool addCustomSortInfo)
        {
            int index = this.SelectCommand.ToLower().IndexOf("order by");
            if (index > -1)
            {
                this.SelectCommand = this.SelectCommand.Substring(0, index);
            }
            if ((this.SortField != "") && addCustomSortInfo)
            {
                this.SelectCommand = this.SelectCommand + " ORDER BY " + this.SortField + "  desc";
            }
        }

        private void BuildControlHierarchy()
        {
            Table child = new Table();
            child.Width = new Unit("100%");
            TableRow row = new TableRow();
            child.Rows.Add(row);
            TableCell cell = new TableCell();
            cell.HorizontalAlign = HorizontalAlign.Left;
            this.BuildCurrentPage(cell);
            row.Cells.Add(cell);
            TableCell cell2 = new TableCell();
            if (this.PagerStyle == AnyOffice.WebControls.PagerStyle.NextPrev)
            {
                this.BuildNextPrevUI(cell2);
            }
            else
            {
                this.BuildNumericPagesUI(cell2);
            }
            cell2.HorizontalAlign = HorizontalAlign.Right;
            row.Cells.Add(cell2);
            this.Controls.Add(child);
        }

        private void BuildCurrentPage(TableCell cell)
        {
            if ((this.CurrentPageIndex < 0) || (this.CurrentPageIndex >= this.TotalPages))
            {
                cell.Text = this.NoPageSelectedText;
            }
            else
            {
                cell.Text = string.Format(this.CurrentPageText, this.CurrentPageIndex + 1, this.TotalPages, this.TotalRecord);
            }
        }

        private void BuildNextPrevUI(TableCell cell)
        {
            bool flag = (this.CurrentPageIndex >= 0) && (this.CurrentPageIndex <= (this.TotalPages - 1));
            bool flag2 = this.CurrentPageIndex > 0;
            bool flag3 = this.CurrentPageIndex < (this.TotalPages - 1);
            LinkButton child = new LinkButton();
            child.ID = "First";
            child.CausesValidation = false;
            child.Click += new EventHandler(this.first_Click);
            child.Text = " 首页 ";
            child.Enabled = flag && flag2;
            cell.Controls.Add(child);
            cell.Controls.Add(new LiteralControl("&nbsp;"));
            LinkButton button2 = new LinkButton();
            button2.ID = "Prev";
            button2.CausesValidation = false;
            button2.Click += new EventHandler(this.prev_Click);
            button2.Text = " 上一页 ";
            button2.Enabled = flag && flag2;
            cell.Controls.Add(button2);
            cell.Controls.Add(new LiteralControl("&nbsp;"));
            LinkButton button3 = new LinkButton();
            button3.ID = "Next";
            button3.CausesValidation = false;
            button3.Click += new EventHandler(this.next_Click);
            button3.Text = " 下一页 ";
            button3.Enabled = flag && flag3;
            cell.Controls.Add(button3);
            cell.Controls.Add(new LiteralControl("&nbsp;"));
            LinkButton button4 = new LinkButton();
            button4.ID = "Last";
            button4.CausesValidation = false;
            button4.Click += new EventHandler(this.last_Click);
            button4.Text = " 尾页 ";
            button4.Enabled = flag && flag3;
            cell.Controls.Add(button4);
            DropDownList list = new DropDownList();
            list.ID = "PageList";
            list.AutoPostBack = true;
            list.SelectedIndexChanged += new EventHandler(this.PageList_Click);
            list.Font.Name = this.Font.Name;
            list.Font.Size = this.Font.Size;
            list.ForeColor = this.ForeColor;
            if ((this.TotalPages <= 0) || (this.CurrentPageIndex == -1))
            {
                list.Items.Add("");
                list.Enabled = false;
                list.SelectedIndex = 0;
            }
            else
            {
                for (int i = 1; i <= this.TotalPages; i++)
                {
                    int num2 = i - 1;
                    ListItem item = new ListItem(i.ToString(), num2.ToString());
                    list.Items.Add(item);
                }
                list.SelectedIndex = this.CurrentPageIndex;
            }
            cell.Controls.Add(list);
        }

        private void BuildNumericPagesUI(TableCell cell)
        {
            DropDownList child = new DropDownList();
            child.ID = "PageList";
            child.AutoPostBack = true;
            child.SelectedIndexChanged += new EventHandler(this.PageList_Click);
            child.Font.Name = this.Font.Name;
            child.Font.Size = this.Font.Size;
            child.ForeColor = this.ForeColor;
            if ((this.TotalPages <= 0) || (this.CurrentPageIndex == -1))
            {
                child.Items.Add("No pages");
                child.Enabled = false;
                child.SelectedIndex = 0;
            }
            else
            {
                for (int i = 1; i <= this.TotalPages; i++)
                {
                    int num2 = i - 1;
                    ListItem item = new ListItem(i.ToString(), num2.ToString());
                    child.Items.Add(item);
                }
                child.SelectedIndex = this.CurrentPageIndex;
            }
            cell.Controls.Add(child);
        }

        private VirtualRecordCount CalculateVirtualRecordCount()
        {
            VirtualRecordCount count = new VirtualRecordCount();
            count.RecordCount = this.GetQueryVirtualCount();
            count.RecordsInLastPage = this.ItemsPerPage;
            int num = count.RecordCount / this.ItemsPerPage;
            int num2 = count.RecordCount % this.ItemsPerPage;
            if (num2 > 0)
            {
                num++;
            }
            count.PageCount = num;
            if (num2 > 0)
            {
                count.RecordsInLastPage = num2;
            }
            return count;
        }

        public void ClearCache()
        {
            if (this.PagingMode == AnyOffice.WebControls.PagingMode.Cached)
            {
                this.Page.Cache.Remove(this.CacheKeyName);
            }
        }

        protected override void CreateChildControls()
        {
            this.Controls.Clear();
            base.ClearChildViewState();
            this.BuildControlHierarchy();
        }

        public override void DataBind()
        {
            base.DataBind();
            base.ChildControlsCreated = false;
            if (this.ControlToPaginate != "")
            {
                this._controlToPaginate = this.Page.FindControl(this.ControlToPaginate);
                if (this._controlToPaginate == null)
                {
                    HtmlForm ctl = (HtmlForm) this.Page.FindControl("Form1");
                    this.FindThePageControl(ctl);
                }
                if (((this._controlToPaginate != null) && ((this._controlToPaginate is BaseDataList) || (this._controlToPaginate is ListControl))) && ((this.ConnectionString != "") && (this.SelectCommand != "")))
                {
                    if (this.PagingMode == AnyOffice.WebControls.PagingMode.Cached)
                    {
                        this.FetchAllData();
                    }
                    else
                    {
                        this.FetchPageData();
                    }
                    BaseDataList list = null;
                    ListControl control = null;
                    if (this._controlToPaginate is BaseDataList)
                    {
                        list = (BaseDataList) this._controlToPaginate;
                        list.DataSource = this._dataSource;
                        list.DataBind();
                    }
                    else if (this._controlToPaginate is ListControl)
                    {
                        control = (ListControl) this._controlToPaginate;
                        control.Items.Clear();
                        control.DataSource = this._dataSource;
                        control.DataBind();
                    }
                }
            }
        }

        private void FetchAllData()
        {
            DataTable table = (DataTable) this.Page.Cache[this.CacheKeyName];
            if (table == null)
            {
                this.AdjustSelectCommand(true);
                DataSet set = new DataSet();
                set = this.Query(this.SelectCommand);
                if ((set != null) && (set.Tables.Count > 0))
                {
                    table = set.Tables[0];
                    _RecordCount = set.Tables[0].Rows.Count;
                    this.Page.Cache.Insert(this.CacheKeyName, set.Tables[0], null, DateTime.Now.AddSeconds((double) this.CacheDuration), Cache.NoSlidingExpiration);
                }
            }
            if (this._dataSource == null)
            {
                this._dataSource = new PagedDataSource();
            }
            this._dataSource.DataSource = table.DefaultView;
            this._dataSource.AllowPaging = true;
            this._dataSource.PageSize = this.ItemsPerPage;
            this.TotalPages = this._dataSource.PageCount;
            this.TotalRecord = table.Rows.Count;
            this.ValidatePageIndex();
            if (this.CurrentPageIndex == -1)
            {
                this._dataSource = null;
            }
            else
            {
                this._dataSource.CurrentPageIndex = this.CurrentPageIndex;
            }
        }

        private void FetchPageData()
        {
            this.AdjustSelectCommand(false);
            VirtualRecordCount countInfo = this.CalculateVirtualRecordCount();
            this.TotalRecord = countInfo.RecordCount;
            this.TotalPages = countInfo.PageCount;
            this.ValidatePageIndex();
            if (this.CurrentPageIndex != -1)
            {
                MySqlCommand selectCommand = this.PrepareCommand(countInfo);
                if (selectCommand != null)
                {
                    MySqlDataAdapter adapter = new MySqlDataAdapter(selectCommand);
                    DataTable dataTable = new DataTable();
                    adapter.Fill(dataTable);
                    if (this._dataSource == null)
                    {
                        this._dataSource = new PagedDataSource();
                    }
                    this._dataSource.AllowCustomPaging = true;
                    this._dataSource.AllowPaging = true;
                    this._dataSource.CurrentPageIndex = 0;
                    this._dataSource.PageSize = dataTable.Rows.Count;
                    this._dataSource.VirtualCount = countInfo.RecordCount;
                    this._dataSource.DataSource = dataTable.DefaultView;
                }
            }
        }

        private void FindThePageControl(Control ctl)
        {
            if (ctl.FindControl(this.ControlToPaginate) != null)
            {
                this._controlToPaginate = ctl.FindControl(this.ControlToPaginate);
            }
            else
            {
                foreach (Control control in ctl.Controls)
                {
                    this.FindThePageControl(control);
                }
            }
        }

        private void first_Click(object sender, EventArgs e)
        {
            this.GoToPage(0);
        }

        private int GetQueryVirtualCount()
        {
            string cmdText = string.Format(this.QueryCountCommandText, this.SelectCommand);
            MySqlConnection connection = new MySqlConnection(this.ConnectionString);
            MySqlCommand command = new MySqlCommand(cmdText, connection);
            command.Connection.Open();
            int num = 0;
            object objA = command.ExecuteScalar();
            if (object.Equals(objA, null) || object.Equals(objA, DBNull.Value))
            {
                return 0;
            }
            num = Convert.ToInt32(objA);
            command.Connection.Close();
            return num;
        }

        private void GoToPage(int pageIndex)
        {
            PageChangedEventArgs e = new PageChangedEventArgs();
            e.OldPageIndex = this.CurrentPageIndex;
            e.NewPageIndex = pageIndex;
            this.CurrentPageIndex = pageIndex;
            this.OnPageIndexChanged(e);
            this.DataBind();
        }

        private void last_Click(object sender, EventArgs e)
        {
            this.GoToPage(this.TotalPages - 1);
        }

        private void next_Click(object sender, EventArgs e)
        {
            this.GoToPage(this.CurrentPageIndex + 1);
        }

        protected virtual void OnPageIndexChanged(PageChangedEventArgs e)
        {
            if (this.PageIndexChanged != null)
            {
                this.PageIndexChanged(this, e);
            }
        }

        private void PageList_Click(object sender, EventArgs e)
        {
            DropDownList list = (DropDownList) sender;
            int pageIndex = Convert.ToInt32(list.SelectedItem.Value);
            this.GoToPage(pageIndex);
        }

        private MySqlCommand PrepareCommand(VirtualRecordCount countInfo)
        {
            if (this.SortField == "")
            {
                MySqlDataAdapter adapter = new MySqlDataAdapter("SET FMTONLY ON;" + this.SelectCommand + ";SET FMTONLY OFF;", this.ConnectionString);
                DataTable dataTable = new DataTable();
                adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
                adapter.Fill(dataTable);
                DataColumn column = null;
                if (dataTable.PrimaryKey.Length > 0)
                {
                    column = dataTable.PrimaryKey[0];
                }
                else
                {
                    column = dataTable.Columns[0];
                }
                this.SortField = column.ColumnName;
            }
            int itemsPerPage = this.ItemsPerPage;
            if (this.CurrentPageIndex == (countInfo.PageCount - 1))
            {
                itemsPerPage = countInfo.RecordsInLastPage;
            }
            string cmdText = string.Format(this.QueryPageCommandText, new object[] { itemsPerPage, this.ItemsPerPage * (this.CurrentPageIndex + 1), this.SelectCommand, this.SortField, "DESC", "ASC" });
            return new MySqlCommand(cmdText, new MySqlConnection(this.ConnectionString));
        }

        private void prev_Click(object sender, EventArgs e)
        {
            this.GoToPage(this.CurrentPageIndex - 1);
        }

        public DataSet Query(string SQLString)
        {
            using (MySqlConnection connection = new MySqlConnection(SQLString))
            {
                DataSet dataSet = new DataSet();
                try
                {
                    connection.Open();
                    new MySqlDataAdapter(SQLString, connection).Fill(dataSet, "ds");
                }
                catch (MySqlException exception)
                {
                    throw new Exception(exception.Message);
                }
                return dataSet;
            }
        }

        protected override void Render(HtmlTextWriter output)
        {
            if ((base.Site != null) && base.Site.DesignMode)
            {
                this.CreateChildControls();
            }
            base.Render(output);
        }

        private void ValidatePageIndex()
        {
            if ((this.CurrentPageIndex < 0) || (this.CurrentPageIndex >= this.TotalPages))
            {
                this.CurrentPageIndex = -1;
            }
        }

        [Description("Gets and sets for how many seconds the data should stay in the cache")]
        public int CacheDuration
        {
            get
            {
                return Convert.ToInt32(this.ViewState["CacheDuration"]);
            }
            set
            {
                this.ViewState["CacheDuration"] = value;
            }
        }

        private string CacheKeyName
        {
            get
            {
                return (this.Page.Request.FilePath + "_" + this.UniqueID + "_Data");
            }
        }

        [Description("Gets and sets the connection string to access the database")]
        public string ConnectionString
        {
            get
            {
                return Convert.ToString(this.ViewState["ConnectionString"]);
            }
            set
            {
                this.ViewState["ConnectionString"] = value;
            }
        }

        [Description("Gets and sets the name of the control to paginate")]
        public string ControlToPaginate
        {
            get
            {
                return Convert.ToString(this.ViewState["ControlToPaginate"]);
            }
            set
            {
                this.ViewState["ControlToPaginate"] = value;
            }
        }

        [Description("Gets and sets the index of the currently displayed page")]
        public int CurrentPageIndex
        {
            get
            {
                return Convert.ToInt32(this.ViewState["CurrentPageIndex"]);
            }
            set
            {
                this.ViewState["CurrentPageIndex"] = value;
            }
        }

        [Description("Gets and sets the number of items to display per page")]
        public int ItemsPerPage
        {
            get
            {
                return Convert.ToInt32(this.ViewState["ItemsPerPage"]);
            }
            set
            {
                this.ViewState["ItemsPerPage"] = value;
            }
        }

        [Browsable(false)]
        public int PageCount
        {
            get
            {
                return this.TotalPages;
            }
        }

        [Description("Indicates the style of the pager's navigation bar")]
        public AnyOffice.WebControls.PagerStyle PagerStyle
        {
            get
            {
                return (AnyOffice.WebControls.PagerStyle) this.ViewState["PagerStyle"];
            }
            set
            {
                this.ViewState["PagerStyle"] = value;
            }
        }

        [Description("Indicates whether the data are retrieved page by page or can be cached")]
        public AnyOffice.WebControls.PagingMode PagingMode
        {
            get
            {
                return (AnyOffice.WebControls.PagingMode) this.ViewState["PagingMode"];
            }
            set
            {
                this.ViewState["PagingMode"] = value;
            }
        }

        [Browsable(false)]
        public int RecordCount
        {
            get
            {
                return this.TotalRecord;
            }
        }

        [Description("Gets and sets the SQL query to get data")]
        public string SelectCommand
        {
            get
            {
                return Convert.ToString(this.ViewState["SelectCommand"]);
            }
            set
            {
                this.ViewState["SelectCommand"] = value;
            }
        }

        [Description("Gets and sets the sort-by field. It is mandatory in NonCached mode.)")]
        public string SortField
        {
            get
            {
                return Convert.ToString(this.ViewState["SortKeyField"]);
            }
            set
            {
                this.ViewState["SortKeyField"] = value;
            }
        }

        protected int TotalPages
        {
            get
            {
                return Convert.ToInt32(this.ViewState["TotalPages"]);
            }
            set
            {
                this.ViewState["TotalPages"] = value;
            }
        }

        protected int TotalRecord
        {
            get
            {
                return Convert.ToInt32(this.ViewState["TotalRecord"]);
            }
            set
            {
                this.ViewState["TotalRecord"] = value;
            }
        }

        public delegate void PageChangedEventHandler(object sender, PageChangedEventArgs e);
    }
}

